﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Bing.Studio
{
    public delegate void ClickFileItemHandler(object sneder, ResourceExplorerEventArgs e);

    public partial class FrmWindowsExplorer : BaseForm
    {
        public event ClickFileItemHandler ClickFileItemEvent;

        public FrmWindowsExplorer()
        {
            InitializeComponent();
        }

        private void FrmWindowsExplorer_Load(object sender, EventArgs e)
        {
            LoadDrive();
        }

        private void LoadDrive()
        {
            var arrDriveName = Directory.GetLogicalDrives();
            this.comboBox1.DataSource = arrDriveName;
            var currentPath = Directory.GetCurrentDirectory();
            var dirInfo = new DirectoryInfo(currentPath);
            LoadDefaultPath(dirInfo);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.treeView1.Nodes.Clear();
            var drive = this.comboBox1.SelectedValue.ToString();
            var rootNode = CreateTreeNode(drive, 0, 1);
            treeView1.Nodes.Add(rootNode);
            LoadSubResource(rootNode);
            rootNode.Expand();
        }

        private void LoadSubResource(TreeNode parent)
        {
            var path = GetPath(parent);
            var dirInfo = new DirectoryInfo(path);
            foreach (var entry in dirInfo.GetDirectories())
            {
                var node = CreateTreeNode(entry.Name, 0, 0);
                var subNode = CreateTreeNode("", 0, 0);
                subNode.Name = "temp";
                node.Nodes.Add(subNode);
                node.Tag = new NodeInfo() { IsFile = false, FilePath = entry.FullName };
                parent.Nodes.Add(node);
            }
            foreach (var entry in dirInfo.GetFiles())
            {
                var node = CreateTreeNode(entry.Name, 2, 2);
                node.Tag = new NodeInfo() { IsFile = true, FilePath = entry.FullName };
                parent.Nodes.Add(node);
            }
        }

        private TreeNode CreateTreeNode(string text, int imageIndex, int selectImageIndex)
        {
            var node = new TreeNode(text, imageIndex, selectImageIndex);
            node.Name = text;
            return node;
        }

        private string GetPath(TreeNode node)
        {
            if (node.Parent == null) return node.Text;
            return GetPath(node.Parent) + "//" + node.Text;
        }

        private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
        {
            e.Node.ImageIndex = 1;
            e.Node.SelectedImageIndex = 1;
            e.Node.Nodes.Clear();
            LoadSubResource(e.Node);
        }

        private void treeView1_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            e.Node.ImageIndex = 0;
            e.Node.SelectedImageIndex = 0;
        }

        private void LoadDefaultPath(DirectoryInfo current)
        {
            var index = this.comboBox1.FindString(current.Root.Name);
            comboBox1.SelectedIndex = index;
            var list = new List<DirectoryInfo>();
            GetDirectoryList(list, current);
            TreeNode node = treeView1.Nodes[0];

            for (var i = list.Count - 1; i >= 0; i--)
            {
                var tmp = node.Nodes.Find(list[i].Name, false);
                if (tmp.Length > 0)
                {
                    node = tmp[0];
                    node.Expand();
                }
            }
        }

        private void GetDirectoryList(List<DirectoryInfo> list, DirectoryInfo info)
        {
            if (info.Parent != null)
            {
                list.Add(info);
                GetDirectoryList(list, info.Parent);
            }
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            var info = treeView1.SelectedNode.Tag as NodeInfo;
            if (info.IsFile && this.ClickFileItemEvent != null)
            {
                ClickFileItemEvent(this, new ResourceExplorerEventArgs(treeView1.SelectedNode.Text, info.FilePath));
            }
        }

        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            TreeNode node = this.treeView1.GetNodeAt(e.X, e.Y);
            if (node != null)
            {
                this.treeView1.SelectedNode = node;
            }
        }
    }

    public class ResourceExplorerEventArgs : EventArgs
    {
        public String FileName { get; private set; }

        public string FullName { get; private set; }

        public ResourceExplorerEventArgs(string fileName, string fullName)
        {
            FileName = fileName;
            FullName = fullName;
        }
    }

    public class NodeInfo
    {
        public bool IsFile { get; set; }
        public string FilePath { get; set; }
    }
}
